home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / book.exe / LANLIB.C < prev    next >
C/C++ Source or Header  |  1991-09-22  |  9KB  |  395 lines

  1. /*
  2. //
  3. // LANLIB.C    Common routines called by both LAN and LANRES
  4. //
  5. // (c) Copyright 1991 Adrian King.
  6. //
  7. //
  8. //        This code was developed for inclusion in the book
  9. //        "Running LANtastic", by Adrian King, published by
  10. //        Bantam Books, October 1991.
  11. //
  12. //    This product uses the TesSeRact(tm) Ram-Resident Library and
  13. //    supports the TesSeRact Standard for Ram-Resident Program Comm-
  14. //    unication. For information about TesSeRact, contact the TesSeRact
  15. //    Development Team at:
  16. //
  17. //        TesSeRact Development Team
  18. //        1657 The Fairways
  19. //        Suite 101
  20. //        Jenkintown PA 19046
  21. //        1-215-884-3373
  22. //
  23. //        Compuserve:    70731,20
  24. //        MCIMAIL:    315-5415
  25. //
  26. // $Header:   C:/USR/LANBOOK/SRC2/LAN/VCS/LANLIB.C_V   1.1   22 Sep 1991  9:16:24  $
  27. //
  28. // $Log:   C:/USR/LANBOOK/SRC2/LAN/VCS/LANLIB.C_V  $
  29. //
  30. //   Rev 1.1   22 Sep 1991  9:16:24
  31. //Added correct TesSeRact copyright notice.
  32. //
  33. //   Rev 1.0   13 Jul 1991 11:19:38
  34. //Initial revision.
  35. //
  36. */
  37.  
  38.     // Standard DOS includes
  39.  
  40. #include "string.h"
  41. #include "time.h"
  42. #include "dos.h"
  43.  
  44.     // NOS specific includes
  45.  
  46. #include "nos.h"
  47. #include "noslib.h"
  48. #include "lan.h"
  49.  
  50.     // Version specific stuff
  51.  
  52.     // Needed for TesSeRact
  53. #include "tess.h"
  54.  
  55. WORD TSRid;                                // Will hold TesSeRact id number
  56. char *TSRIdStr = "A.KING01";            // TesSeRact id string
  57.  
  58.     // Global external data
  59.  
  60.     // Global data held in this module
  61.  
  62.     //
  63.     //    Error messages indexed by error numbers.
  64.     //    No checking is performed. The callers are 
  65.     //    trusted to get it right.
  66.     //
  67. char *LANerr[] = {
  68.  
  69.     "",                                    // 0 is not used
  70.     "LANRES module not loaded",
  71.     "LANRES module already loaded",
  72.     "No interrupt vector available",
  73.     "NETBIOS not loaded",
  74.     "NOS not loaded",
  75.     "Unable to get machine name",
  76.     "Error in NOS_Get_Msg_Vector",
  77.     "Error in NOS_Set_Msg_Flag",
  78.     "Error in NOS_Set_Msg_Vec",
  79.     "No NETBIOS NCBs left to allocate",
  80.     "No LAN software loaded",
  81.     "No network host name specified",
  82.     "Error in NOS_Get_Msg_Flag",
  83.     "Error trying to go resident",
  84.     "No machine name defined",
  85.     "Error in NOSGetDOSVector",
  86.     "Error in NOSSetDOSVector",
  87.     "Error sending network message",
  88.  
  89.     (char *)0                            // Place holder
  90. };
  91.  
  92.  
  93. struct lannode lannode[D_NODES];        // Table of active nodes.
  94.  
  95. char cpNRSL[] = "----";                    // Says what's loaded on this node
  96.  
  97.     //
  98.     //    FATAL
  99.     //
  100.     //    Report fatal error and quit
  101.     //
  102.  
  103. void FATAL(N)
  104. int N;
  105. {
  106.     NOSperror(LANerr[N]); 
  107. #ifdef __TURBOC__
  108.     _exit(N);
  109. #endif
  110. #ifndef __TURBOC__
  111.     exit(N);
  112. #endif
  113. }
  114.  
  115.     //
  116.     //    SENDMESSAGE
  117.     //
  118.     //    Send a message block to the named host using the NOS message
  119.     //    service.
  120.     //
  121.     //    Called with:
  122.     //
  123.     //        m        is a message buffer to use
  124.     //        host    is name of destination host
  125.     //        msgtype    is type of message to send
  126.     //        msgtext is array of bytes to send as message text field
  127.     //        msglen    is -1 if text is already in buffer, or is the #
  128.     //                of bytes to send
  129.     //
  130.  
  131. int sendmessage(m, host, msgtype, msgtext, msglen)
  132. struct message_buffer *m;
  133. char *host;
  134. int msgtype;
  135. char *msgtext;
  136. int msglen;        
  137. {
  138.     int i;
  139.  
  140.     m->MB_type = msgtype;                // Set message type
  141.                                         // And destination host name
  142.     for (i = 0; i < D_NAMESZ; i++)
  143.         m->MB_machine[i] = host[i];
  144.                                         // and set others to null strings
  145.     m->MB_server[0] = m->MB_user[0] = '\0';
  146.  
  147.     if (msglen != -1){                    // Need to copy in the string?
  148.         for (i = 0; i < msglen; i++)
  149.             m->MB_text[i] = msgtext[i];
  150.         for (i = msglen; i < MB_textlen; i++)    // Space fill the rest
  151.             m->MB_text[i] = ' ';
  152.     }
  153.     
  154. #ifdef BACKGROUND
  155.     msgstats.out++;                        // Update transmission count
  156. #endif
  157.     return NOSSendMsg(m);
  158. }
  159.  
  160.     //
  161.     //    LANLIBCHECK
  162.     //
  163.     //    Make sure we can communicate with the resident library.
  164.     //    Abort if we cannot.
  165.     //
  166.  
  167. void lanlibcheck()
  168. {
  169.         //
  170.         // This will only ever be called by the foreground LAN program
  171.         //
  172.     if (TsCheckResident((char far *)TSRIdStr, (unsigned far *)&TSRid) == 0)
  173.         FATAL(E_NOLANLIB);
  174. }
  175.  
  176. #ifndef    __TURBOC__
  177.     //
  178.     //    DELAY
  179.     //
  180.     //    Delay by looping for a specified time
  181.     //    Turbo C has this as a library routine. 
  182.     //
  183.  
  184. void delay(nMSecs)
  185. unsigned nMSecs;
  186. {
  187.     time_t T, tEnd;
  188.  
  189.     time(&T);
  190.     tEnd = T + ((time_t)nMSecs/1000);
  191.     while (T < tEnd)
  192.         time(&T);
  193. }
  194. #endif
  195.  
  196.     //
  197.     //    COPYFARTONEAR
  198.     //
  199.     //    Copy a FAR buffer to a NEAR place
  200.     //
  201.  
  202. void copyfartonear(fpM, cpM, n)
  203. char far *fpM;
  204. char *cpM;
  205. int n;
  206. {
  207.     int i;
  208.  
  209.     for (i=0; i < n; i++)
  210.         *cpM++ = *fpM++;
  211. }
  212.  
  213.     //
  214.     //    INITNODETABLE
  215.     //
  216.     //    Initialize the network node table so that all entries are
  217.     //    empty.
  218.     //
  219.  
  220. void initnodetable()
  221. {
  222.     int i;
  223.  
  224.     for (i = 0; i < D_NODES; i++)
  225.         lannode[i].cpName[0] = '\0';
  226. }
  227.  
  228.     //
  229.     //    REFRESHNAMES
  230.     //
  231.     //    Update the table of nodes currently active on the LAN
  232.     //
  233.  
  234. void refreshnames()
  235. {
  236.     int i;
  237.     struct message_buffer M;
  238.     char *cpM = "Status enquiry";
  239.  
  240.     // Send a broadcast that causes every node on the network to
  241.     // respond. The entry in the lannode table for the responding
  242.     // machine will be updated when the reply comes in. 
  243.     //
  244.     // Only nodes running LANRES will know how to respond to the
  245.     // enquiry message. Others will simply put it up on the screen
  246.     // as an unsolicited message.
  247.     //
  248.     // Should really also have a timer that goes off and causes us
  249.     // to send a status request broadcast. If there is no response, 
  250.     // then we should assume that the node has gone away and its 
  251.     // entry won't get re-instated.
  252.     //
  253.  
  254.             // 
  255.             // First empty the current background node table.
  256.             // Call LANRES via the TesSeRact library. Pass in a zero
  257.             // value to denote the node table should be cleared. 
  258.             //
  259.     (void)TsCallUserProc(TSRid, (void far *)0);
  260.  
  261.                                         // Ask for status network wide
  262.     if (sendmessage(&M, "", MBT_LANstatus, cpM, strlen(cpM)) == -1)
  263.         NOSprintstr("refreshnames() sendmessage error\n");
  264.  
  265. }
  266.  
  267.     //
  268.     //    ADDNAME
  269.     //
  270.     //    Add or update the name of a LAN node in the global table
  271.     //
  272.  
  273. int addname(cpS, n)
  274. char *cpS;            // Points to name. May not be null terminated.
  275. int n;                // Flags (same as NOSPresence returns.)
  276. {
  277.     int i;
  278.     char *cp;
  279.  
  280.     cp = cpS;
  281.     while (*cp){
  282.         if (*cp == ' ')
  283.             *cp = '\0';                        // Null terminate the name
  284.         cp++;
  285.     }
  286.  
  287.     for (i = 0; i < D_NODES; i++){
  288.         if (nodenamecmp(cpS, lannode[i].cpName) == 0){
  289.                                             // Names match, update flags word
  290.             lannode[i].wFlags = n;
  291.             return 0;
  292.         }
  293.     }
  294.                                               // Not present, add to table
  295.     for (i = 0; i < D_NODES; i++){
  296.         if (lannode[i].cpName[0] == '\0'){ 
  297.                                             // Found a free entry
  298.             cp = lannode[i].cpName;            // Add to table
  299.             while ((*cp++ = *cpS++) != '\0')
  300.                 ;
  301.             lannode[i].wFlags = n;
  302.             return 0;                        // Say okay
  303.         }
  304.     }
  305.  
  306.     return -1;                                // Table full - "cannot happen"
  307. }
  308.  
  309.     //
  310.     //    NODENAMECMP
  311.     //
  312.     //    Compare two node names. Comparison is case insensitive
  313.     //    and trailing spaces are not significant. Return 0 if
  314.     //    names match, non-zero if not (like strcmpX().)
  315.     //
  316.  
  317. nodenamecmp(cp1, cp2)
  318. char *cp1, *cp2;
  319. {
  320.     char *cp;
  321.  
  322.                     // Put a null on trailing spaces
  323.     cp = strchr(cp1, ' ');    
  324.     if (cp != NULL)
  325.         *cp = '\0';
  326.  
  327.     cp = strchr(cp2, ' ');
  328.     if (cp !=NULL)
  329.         *cp = '\0';
  330.  
  331.     return strcmpi(cp1, cp2);
  332. }    
  333.  
  334. //
  335. //    GENNRSL        Generate NRSL string from current machine status flags
  336. //
  337.  
  338. void gennrsl()
  339. {
  340.     int i;
  341.  
  342.     i = NOSPresence();                // Get flags and set up string
  343.  
  344.     cpNRSL[0] = 'N';                // LANBIOS must be running
  345.     cpNRSL[1] = (i&D_redir)?'R':'-';
  346.     cpNRSL[2] = (i&D_server)?'S':'-';
  347.     cpNRSL[3] = (i&D_lanpup)?'L':'-';
  348.  
  349.     lannode[0].wFlags = i;            // Refresh the flags word (server may
  350.                                     // have been loaded later for example.)
  351.  
  352. }
  353.  
  354. //
  355. //    SIZEOFCODE
  356. //
  357. //    Adapted from the example given in the TesSeRact documentation.
  358. //    We make sure that all of the requesting program stays in memory.
  359. //
  360. //    Return from this function is the number of paragraphs to
  361. //    keep when going resident.
  362. //
  363.  
  364. unsigned SizeOfCode()
  365. {
  366. #ifdef  MSC5
  367.     unsigned int far *PSP;              // far pointer to PSP
  368.     extern unsigned _psp,               // segment of PSP    
  369.                     _atopsp;            // undocumented offset of top of
  370.                                         // MSC 5.0 stack
  371. #endif  /* End of MSC5 */
  372. #ifdef  __TURBOC__
  373.     extern unsigned _psp,               // segment address of PSP
  374.                     __heapbase,         // undocumented offset of base of
  375.                                         // Turbo C heap area
  376.                     _heaplen,           // size of heap 
  377.                     _stklen;            // size of stack
  378. #endif  /* End of __TURBOC__ */
  379.  
  380.     unsigned used;                      // variable to save paragraphs
  381.     struct SREGS sregs;                 // segment register structure
  382.  
  383.     segread(&sregs);                    // read the segment regs 
  384.  
  385. #ifdef __TURBOC__
  386.     used = (((__heapbase + 16 + _heaplen + _stklen) >> 4) + sregs.ds) - _psp;
  387. #endif
  388. #ifdef MSC5
  389.     FP_SEG(PSP) = _psp;                 // segment address of psp 
  390.     FP_OFF(PSP) = 0;                       // offset of the psp is zero
  391.     used = *(PSP+1) - _psp;             // number of paras used by program
  392. #endif
  393.     return(used);                         // return number of paragraphs
  394. }
  395.